/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-09-09     SenyPC       the first version
 */

#include "device_status.h"
#include "drivers/pin.h"
#include "device_data.h"

#include "net_task.h"
#include "device_extend.h"

#define DBG_TAG "dev.status"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#if DEVICE_STATUS_SF_ENABLE
#define STATUS_SF_ON()              dev_pin_write(_type_status_dev.status_sf_pin, PIN_LOW)
#define STATUS_SF_OFF()             dev_pin_write(_type_status_dev.status_sf_pin, PIN_HIGH)
#endif

#define STATUS_ERROR_ON()           dev_pin_write(_type_status_dev.status_error_pin, PIN_LOW)
#define STATUS_ERROR_OFF()          dev_pin_write(_type_status_dev.status_error_pin, PIN_HIGH)

#define STATUS_STOP()               dev_pin_write(_type_status_dev.status_run_pin, PIN_LOW)
#define STATUS_RUN()                dev_pin_write(_type_status_dev.status_run_pin, PIN_HIGH)

#define GET_RUN_STATE()             dev_pin_read(_type_status_dev.mcu_run_pin)
#define GET_MCU_PD_STATE()          dev_pin_read(_type_status_dev.mcu_pd_pin)


static struct device_status_type _type_status_dev = {0};

static int dev_status_init( void ) {
    device_status_type_t dev = &_type_status_dev;
#if DEVICE_STATUS_SF_ENABLE
    dev->status_sf_pin = GET_PIN(C, 1);
    dev_pin_mode(dev->status_sf_pin, PIN_MODE_OUTPUT);
    STATUS_SF_OFF();
#endif

    dev->mcu_run_pin = GET_PIN(D, 1);
    dev->status_error_pin = GET_PIN(A, 2);
    dev->status_run_pin = GET_PIN(E, 4);
    dev->mcu_pd_pin = GET_PIN(E, 12);

    dev_pin_mode(dev->mcu_run_pin, PIN_MODE_INPUT_PULLUP);
    dev_pin_mode(dev->status_error_pin, PIN_MODE_OUTPUT);
    dev_pin_mode(dev->status_run_pin, PIN_MODE_OUTPUT);
    dev_pin_mode(dev->mcu_pd_pin, PIN_MODE_INPUT_PULLUP);

    STATUS_ERROR_OFF();
    STATUS_STOP();

    return 0;
}
INIT_DEVICE_EXPORT(dev_status_init);

#define     NET_INIT_TIME_OUT       (5000)
#define     DEV_EXT_INIT_TIME_OUT   (5000)
#define     LED_STATUS_LINK_DELAY   (500)
void dev_status_entry(void *parameter) {
    int time_out = 0;
    rt_base_t pin_val = PIN_LOW;
    dev_delay(10);
    //如果网线是连接上的，需要等待网络初始化完毕，如果未插入网线，则不需要等待
    if(net_is_link_up() != 0) {
        while((time_out < NET_INIT_TIME_OUT) || (net_is_eth_up() == 0)) {
            dev_pin_write(_type_status_dev.status_error_pin, pin_val);
            dev_delay(LED_STATUS_LINK_DELAY);
            pin_val ^= PIN_HIGH;
            time_out += LED_STATUS_LINK_DELAY;
        }
        if(net_is_eth_up() == 0) {
            STATUS_ERROR_ON();
            LOG_E("net init error.");
            return ;
        }
    }
    time_out = 0;
    if(dev_ext_get_status() != 1) {
        while((time_out < DEV_EXT_INIT_TIME_OUT) || (dev_ext_get_status() != 1)) {
            dev_pin_write(_type_status_dev.status_error_pin, pin_val);
            dev_delay(LED_STATUS_LINK_DELAY);
            pin_val ^= PIN_HIGH;
            time_out += LED_STATUS_LINK_DELAY;
        }
        if(dev_ext_get_status() != 1) {
            STATUS_ERROR_ON();
            LOG_E("dev_ext init error.");
            return ;
        }
    }
    time_out = 0;
    dev_delay(10);
    STATUS_ERROR_OFF();
    while(1){
        dev_delay(1000);
    }
}


static int status_task_init(void){
    //启动设备状态扫描线程
    rt_thread_t status_task = rt_thread_create("status_task",dev_status_entry, NULL, 1024, 20, 10);
    if (status_task != RT_NULL) {
        rt_thread_startup(status_task);
    } else {
        LOG_E("status_task thread initialization failed!");
    }
    return 0;
}
INIT_APP_EXPORT(status_task_init);
